package com.lx.interceptor;

import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.lx.annotation.CheckPermission;
import com.lx.entity.User;
import com.lx.service.UserService;
import com.lx.util.JwtUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.Date;
import java.util.concurrent.TimeUnit;

@Component
public class UserCheckInterceptor implements HandlerInterceptor {

	public static final Logger log = LoggerFactory.getLogger(UserCheckInterceptor.class);
	
	private StringRedisTemplate redisTemplate;
	private UserService userService;

	@Autowired
	public UserCheckInterceptor(StringRedisTemplate redisTemplate, UserService userService) {
		this.redisTemplate = redisTemplate;
		this.userService = userService;
	}

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		log.info("请求地址：" + request.getRequestURI());
		String token = request.getHeader("Authorization");
		log.info("token:" + token);
		//验证是否登录
		/*if (token == null || token.equals("")) {
			// 没有登录
			throw new RuntimeException("未登录");
		}*/
		
		//验证token
		Integer userID = null;
		try {
			if(token != null) { //用户未登录也可以访问首页
				userID = JwtUtil.getUserID(token);
				String serverToken = redisTemplate.opsForValue().get(userID.toString());
				if(serverToken == null) {
					throw new RuntimeException("登录超时");
				}
				if(!token.equals(serverToken)) {
					log.info("redis中token: " + serverToken);
					log.info("页面传过来的token: " + token);
					throw new RuntimeException("验签错误");
				}

				//toke延期
				Date exp = JwtUtil.getExpires(token);
				if(exp.getTime() - System.currentTimeMillis() <= 5 * 60 * 1000 ) { //原5 * 60 * 1000
					//进行token置换
					String newToken = JwtUtil.createToken(userID);
					redisTemplate.opsForValue().set(userID.toString(), newToken, 30, TimeUnit.MINUTES); //原 30
					response.setHeader("Access-Control-Expose-Headers", "x-token");
					response.setHeader("x-token", newToken);
					log.info("Token已更新: userID={}, newToken={}", userID, newToken);
				}
			}
		}catch (SignatureVerificationException e) {
			throw new RuntimeException("验签错误");
		}catch (TokenExpiredException e) {
			throw new RuntimeException("登录超时");
		}

		
		//验证权限
		boolean isHandlerMethod = handler instanceof HandlerMethod;
		if (!isHandlerMethod) {
			return true;
		}
		HandlerMethod handlerMethod = (HandlerMethod) handler;
		CheckPermission checkPermission = handlerMethod.getMethodAnnotation(CheckPermission.class);
		if(checkPermission == null) {
//			throw new RuntimeException("无权限");
			return true; //为null则表示所有用户角色都可以访问
		}

		String[] types =  checkPermission.value();
		log.info("角色："+Arrays.toString(types) + ", userID: " + userID);
		if(checkRole(userID, types)) {
			return true;
		}else {
			throw new RuntimeException("权限不足");
		}
	}
	
	public boolean checkRole(Integer userID,String[] types) {
		if(userID == null) return false;
		User user = userService.selectById(userID);
		String userType = String.valueOf(user.getType());
		for(String type : types) {
			if(type.equals(userType)) {
				return true;
			}
		}
		return false;
	}

}
